package www.bplead.com.mydemo.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.Date;

import www.bplead.com.mydemo.R;

/**
 * Created by wangyangzi on 2016/9/17.
 */
public class RefreshListView extends ListView implements AbsListView.OnScrollListener {

    private static final String TAG = "RefreshListView";

    //头部下拉刷新View
    View headerView;
    //头部布局的高度
    int headerHeight;
    //头部相关控件
    TextView tipTV;
    TextView updatetimeTV;
    ImageView arrowImg;
    ImageView loadingImg;
    //底部加载更多View
    View footerView;
    //底部相关控件
    View footerViewWrap;
    TextView footerTipTV;
    ImageView footerLoadingImg;
    //滑动到底部加载更多数据时的状态
    int currentLoadMoreDataState = 0;
    static final int more_data_common = 0;//正常状态
    static final int more_data_loading = 1;//加载中
    //滚动时第一个可见项
    int firstVisibleItem;
    //是否在最顶部下拉
    boolean isTop;
    //当在最顶部时手指按下时的Y坐标位置
    int startY;
    //滚动状态
    int scrollState;
    //当前状态
    int currentState = 0;
    //滚动状态
    static final int NONE = 0;//初始状态
    static final int PULL = 1;//下拉状态
    static final int RELEASE = 2;//释放状态
    static final int REFRESH = 3;//刷新状态
    //数据刷新接口，实现类去初始化
    LoadDataListener loadDataListener;

    public RefreshListView(Context context) {
        super(context);
        initView(context);
    }

    public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    public RefreshListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    private void initView(Context context){
        LayoutInflater inflate1 = LayoutInflater.from(context);
        headerView = inflate1.inflate(R.layout.listview_header,null);
        tipTV = (TextView) headerView.findViewById(R.id.listview_refresh_tip);
        updatetimeTV = (TextView) headerView.findViewById(R.id.listview_refresh_updatetime);
        arrowImg = (ImageView) headerView.findViewById(R.id.listview_refresh_arrow);
        loadingImg = (ImageView) headerView.findViewById(R.id.listview_refresh_loading);
        //测量headerView在父布局中所占宽高
        headerView.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        //获得头部布局的高度
        headerHeight = headerView.getMeasuredHeight();
        setTopPadding(-headerHeight);
        this.addHeaderView(headerView);

        LayoutInflater inflate2 = LayoutInflater.from(context);
        footerView = inflate2.inflate(R.layout.listview_footer,null);
        footerViewWrap = footerView.findViewById(R.id.wrap_listview_loadmore);
        footerTipTV = (TextView) footerView.findViewById(R.id.listview_more_tip);
        footerLoadingImg = (ImageView) footerView.findViewById(R.id.listview_more_loading);
        this.addFooterView(footerView);

        this.setOnScrollListener(this);
    }

    private void setTopPadding(int topPadding){
        headerView.setPadding(headerView.getPaddingLeft(),topPadding,headerView.getPaddingRight(),headerView.getPaddingBottom());
        headerView.invalidate();
    }

    /**
     * 手势改变监听
     * @param ev
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            //手指按下:
            case MotionEvent.ACTION_DOWN:
                if(firstVisibleItem == 0){
                    isTop = true;
                    startY = (int) ev.getY();
                }
                break;
            //手指移动
            case MotionEvent.ACTION_MOVE:
                onMove(ev);
                break;
            //手指抬起
            case MotionEvent.ACTION_UP:
                if(currentState == RELEASE){
                    currentState = REFRESH;
                    refreshViewByState();
                    loadDataListener.pullRefreshRequest();
                }else if(currentState == PULL){
                    currentState = NONE;
                    isTop = false;
                    refreshViewByState();
                }
                break;
        }

        return super.onTouchEvent(ev);
    }

    private void onMove(MotionEvent ev){
        //在最顶端时才执行下拉刷新数据功能
        if(!isTop){
            return;
        }
        //如果是正处于加载更多数据时则不允许同时去下拉刷新
        if(currentLoadMoreDataState == more_data_loading){
            return;
        }
        //滑动了多少距离
        int space = (int) (ev.getY() - startY);
        int topPadding = space - headerHeight;
        switch (currentState){
            case NONE:
                if(space > 0){
                    currentState = PULL;
                    refreshViewByState();
                }
                break;
            case PULL:
                setTopPadding(topPadding);
                if(space > headerHeight + 30){
                    currentState = RELEASE;
                    refreshViewByState();
                }
                break;
            case RELEASE:
                setTopPadding(topPadding);
                if(space < headerHeight + 30){
                    currentState = PULL;
                    refreshViewByState();
                }
                break;
        }
    }


    /**
     * 根据当前状态改变界面显示
     */
    private void refreshViewByState(){
        //创建下拉和上拉动画
        RotateAnimation downToUpAnim = new RotateAnimation(0,180,RotateAnimation.RELATIVE_TO_SELF,0.5f,RotateAnimation.RELATIVE_TO_SELF,0.5f);
        downToUpAnim.setDuration(500);
        downToUpAnim.setFillAfter(true);
        RotateAnimation upToDownAnim = new RotateAnimation(180,0,RotateAnimation.RELATIVE_TO_SELF,0.5f,RotateAnimation.RELATIVE_TO_SELF,0.5f);
        upToDownAnim.setDuration(500);
        upToDownAnim.setFillAfter(true);

        //根据header状态的不同显示不同的动画效果
        switch (currentState){
            case NONE:
                arrowImg.clearAnimation();
                setTopPadding(-headerHeight);
                break;
            case PULL:
                arrowImg.setVisibility(VISIBLE);
                loadingImg.setVisibility(GONE);
                arrowImg.clearAnimation();
                arrowImg.setAnimation(upToDownAnim);
                tipTV.setText("下拉可以刷新");
                break;
            case RELEASE:
                arrowImg.setVisibility(VISIBLE);
                loadingImg.setVisibility(GONE);
                arrowImg.clearAnimation();
                arrowImg.setAnimation(downToUpAnim);
                tipTV.setText("松开可以刷新");
                break;
            case REFRESH:
                setTopPadding(20);
                arrowImg.setVisibility(GONE);
                loadingImg.setVisibility(VISIBLE);
                arrowImg.clearAnimation();
                tipTV.setText("正在刷新...");
                break;
        }
    }

    /**
     * 加载最新数据完成
     */
    public void loadLatestDataComplete(){
        currentState = NONE;
        isTop = false;
        refreshViewByState();
        SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
        Date date = new Date(System.currentTimeMillis());
        String time = format.format(date);
        updatetimeTV.setText("最近更新时间：" + time);
    }

    /**
     * 加载更多数据完成
     */
    public void loadMoreDataComplete(){
        currentLoadMoreDataState = more_data_common;
        footerViewWrap.setVisibility(GONE);
    }

    /**
     *
     * @param view
     * @param scrollState
     */
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        this.scrollState = scrollState;
        //当滚动到了底部，加载更多数据
        if (getLastVisiblePosition() == (getCount() - 1)) {
            if(currentLoadMoreDataState == more_data_common && currentState == NONE){
                currentLoadMoreDataState = more_data_loading;
                footerViewWrap.setVisibility(VISIBLE);
                setSelection(getBottom());
                loadDataListener.loadMoreRequest();
            }
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        this.firstVisibleItem = firstVisibleItem;
    }

    public void setLoadDataListener(LoadDataListener loadDataListener){
        this.loadDataListener = loadDataListener;
    }

    /**
     * 下拉刷新和加载更多请求最新数据接口
     */
    public interface LoadDataListener{
        void pullRefreshRequest();
        void loadMoreRequest();
    }
}
